<?php
/**
 * Created by PhpStorm.
 * User: peter
 * Date: 2018/6/29
 * Time: 上午11:12
 */

namespace app\mall\logic;


use app\model\Express;
use app\model\GoodsAttributeAttach;
use app\model\OrderAttach;
use app\model\OrderProcess;
use app\model\ShoppingCart;
use extend\Functions;
use extend\STATUS_CODE;

class Order
{
    /**
     * @purpose 确认收货
     * @param string $order_no
     * @param int $uid
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function confirm (string $order_no, int $uid): array
    {
        $order              = new \app\model\Order();
        $order_process      = new OrderProcess();
        $order_info       = $order
            ->where('order_no', $order_no)
            ->field('id,status')
            ->find();
        if ($order_info->status !== 3) {
            return Functions::result(
                STATUS_CODE::SUCCESS,
                '订单状态错误!'
            );
        }
        $order_data         = [];
        $order_data['status'] = 7;

        $order_process_data   = [];
        $order_process_data['order_id'] = $order_info->id;
        $order_process_data['status']   = 7;
        $order_process_data['operator_type']   = 1;
        $order_process_data['operator_id']   = $uid;
        $order_process_data['description']   = '确认收货,交易完成';
        $order->startTrans();
        $order_result = $order
            ->isUpdate(true)
            ->save($order_data, ['id' => $order_info->id, 'uid' => $uid]);
        $order_process_result = $order_process
            ->data($order_process_data)
            ->save();
        if ($order_result && $order_process_result) {
            $order->commit();
            // 分销结算
            Profit::settlement($order_info->id, $order_no);
            return Functions::result(
                STATUS_CODE::SUCCESS,
                '确认成功'
            );
        }
        $order->rollback();
        return Functions::result(
            STATUS_CODE::FAIL,
            '确认失败'
        );
    }

    /**
     * @purpose 通过订单编号获取订单详情
     * @param string $order_no
     * @param int $uid
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function detailByOrderNo (string $order_no, int $uid): array
    {
        if (!$order_no) {
            return Functions::result(
                STATUS_CODE::PARAMETER_ERROR,
                '参数错误!'
            );
        }
        $order      = new \app\model\Order();
        $order_process = new OrderProcess();
        $express    = new Express();
        $order_info     = $order
            ->with(['attach' => function ($query) {
                $query->field('order_id,goods_id,goods_number,goods_price,number,title,thumb,spec, (goods_price * number) as total_price');
            }])
            ->where(['uid' => $uid, 'order_no' => $order_no])
            ->field('id,status,cancel_reason,order_no,pay_type,address,message,contacts,contacts_mobile,express_company,express_no,FROM_UNIXTIME(create_at, \'%Y-%m-%d %H:%i:%s\') as create_time')
            ->find();
        if ($order_info) {
            $order_info['total_price'] = 0;
            $order_info['total_number'] = 0;
            foreach ($order_info['attach'] as $val) {
                $order_info['total_price'] += $val['total_price'];
                $order_info['total_number'] += $val['number'];
            }
        } else {
            return Functions::result(
                STATUS_CODE::FAIL,
                'order is not find!'
            );
        }
        // 获取订单流程
        $process = $order_process
            ->where('order_id', $order_info['id'])
            ->field('status,description,FROM_UNIXTIME(create_at, \'%Y-%m-%d %H:%i:%s\') as create_time')
            ->order('create_at desc')
            ->select();
        // 获取订单物流信息
        $express_data = $express
            ->where('order_no', $order_info['order_no'])
            ->field('process')
            ->find();
        $order_info['express'] = $express_data->process;
        $order_info['process'] = $process;
        return Functions::result(
            STATUS_CODE::SUCCESS,
            $order_info
        );
    }
    /**
     * @purpose 通过状态获取订单列表
     * @param int $uid
     * @param int $status
     * @param int $page
     * @param int $size
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function itemByStatus (int $uid, int $status = 0, int $page, int $size): array
    {
        $model      = new \app\model\Order();
        $where = [];
        $where['uid'] = $uid;
        if ($status) {
            $where['status'] = $status;
        }
        $result = $model
            ->with(['attach' => function ($query) {
                $query->field('order_id,goods_id,goods_number,goods_price,number,title,thumb,spec, (goods_price * number) as total_price');
            }])
            ->where($where)
            ->where('status', '<>', 5)
            ->field('id,status,order_no,FROM_UNIXTIME(create_at, \'%Y-%m-%d %H:%i:%s\') as create_time')
            ->order('create_at desc')
            ->page($page, $size)
            ->select();
        if ($result) {
            foreach ($result as $key => $item) {
                $result[$key]['total_price'] = 0;
                $result[$key]['total_number'] = 0;
                foreach ($item['attach'] as $val) {
                    $result[$key]['total_price'] += $val['total_price'];
                    $result[$key]['total_number'] += $val['number'];
                }
            }
        }
        return Functions::result(
            STATUS_CODE::SUCCESS,
            $result
        );
    }
    /**
     * @purpose 查询用户订单每个状态的数量
     * @param int $uid
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function statusNumber (int $uid): array
    {
        $model      = new \app\model\Order();
        $where['uid'] = $uid;
        $wait_pay           = $model->total(array_merge($where, ['status' => 1]));
        $pending_delivery   = $model->total(array_merge($where, ['status' => 2]));
        $wait_received      = $model->total(array_merge($where, ['status' => 3]));

        return Functions::result(
            STATUS_CODE::SUCCESS,
            [
                'wait_pay' => $wait_pay,
                'pending_delivery' => $pending_delivery,
                'wait_received' => $wait_received
            ]
        );
    }
    /**
     * @purpose 创建订单
     * @param array $data
     * @param int $uid
     * @param array $cart_ids
     * @return array
     * @throws \Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function placeAnOrder (
        array $data,
        int $uid):array
    {
        if (!$data['address_id']) {
            return Functions::result(
                STATUS_CODE::PARAMETER_ERROR,
                '缺少收货地址'
            );
        }
        if (!isset($data['goods']) || empty($data['goods'])) {
            return Functions::result(
                STATUS_CODE::PARAMETER_ERROR,
                '参数错误!'
            );
        }
        $address_info           = Address::info($data['address_id'], $uid);
        if ($address_info['data']) {
            $address_info       = $address_info['data'];
        }
        $order                  = new \app\model\Order();
        $order_attach           = new OrderAttach();
        $order_process         = new OrderProcess();
        // 组装订单主表数据
        $order_data             = [];
        $order_data['uid']      = $uid;
        $order_data['status']   = 1;
        $order_data['order_no'] = date('Ymdhis', time()).Functions::random(6);
        RE_ORDER_NO:
            $order_data['order_no'] = date('Ymdhis', time()).Functions::random(6);
        if ($order->total(['order_no' => $order_data['order_no']]) > 0) {
            goto RE_ORDER_NO;
        }
        if (isset($data['message'])) {
            $order_data['message']  = $data['message'];
        }
        $order_data['address'][]    = $address_info['province']->name;
        $order_data['address'][]    = $address_info['city']->name;
        $order_data['address'][]    = $address_info['county']->name;
        if (isset($address_info['town']->name)) {
            $order_data['address'][]    = $address_info['town']->name;
        }
        $order_data['address'][]        = $address_info['detail'];
        $order_data['address']          = implode(' ', $order_data['address']);
        $order_data['contacts']         = $address_info['name'];
        $order_data['contacts_mobile']  = $address_info['mobile'];
        $order->startTrans();
        $main_order = $order->isUpdate(false)->save($order_data);
        $order_id = $order->id;
        $order_attach_data  = [];
        $goods_attribute_attach = new GoodsAttributeAttach();
        //组装订单附表数据
        foreach ($data['goods'] as $goods) {
            $goods_data = [];
            $_data = $goods_attribute_attach
                ->with(['goods' => function($query) {
                    $query->field('id,title');
                }])
                ->where(['goods_id' => $goods['goods_id'], 'number' => $goods['goods_number']])
                ->field('goods_id,price,thumb,attach')
                ->find();
            $goods_data['order_id']       = $order_id;
            $goods_data['goods_id']       = $goods['goods_id'];
            $goods_data['number']         = $goods['number'];
            $goods_data['goods_number']   = $goods['goods_number'];
            $goods_data['goods_price']    = $_data->price;
            $goods_data['thumb']          = $_data->thumb;
            $goods_data['title']          = $_data->goods->title;
            $goods_data['spec']           = '';
            foreach ($_data->attach as $attach) {
                $goods_data['spec'] .= ($attach->name).' ';
            }
            $goods_data['spec'] = trim($goods_data['spec']);
            array_push($order_attach_data, $goods_data);
        }
        $result = $order_attach
            ->isUpdate(false)
            ->saveAll($order_attach_data);
        // 如果是从购物车过来的,则在订单创建成功之后删除购物车对应的数据
        $delete_cart_result = true;
        if (isset($data['cart_ids']) && !empty($data['cart_ids'])) {
            $cart = new ShoppingCart();
            $delete_cart_result = (bool) $cart
                ->where(['id' => $data['cart_ids']])
                ->delete();
        }
        // 检测是否每条附表数据都添加成功
        $add_all_order_attach = true;
        foreach($result as $v) {
            if (!$v) {
                $add_all_order_attach = false;
            }
        }
        // 记录订单操作流程
        $result_order_process = (bool) $order_process
            ->isUpdate(false)
            ->save([
                'order_id' => $order_id,
                'status'   => 1,
                'operator_type' => 1,
                'operator_id' => $uid,
                'description' => '订单创建成功'
            ]);
        if ($main_order &&
            $add_all_order_attach &&
            $delete_cart_result &&
            $result_order_process) {
            $order->commit();
            return Functions::result(
                STATUS_CODE::SUCCESS,
                [
                    'order_no' => $order_data['order_no']
                ]
            );
        }
        $order->rollback();
        return Functions::result(
            STATUS_CODE::CREATE_FAIL,
            '订单创建失败!'
        );
    }
    /**
     * @purpose 直接购买后期商品列表
     * @param int $goods_id
     * @param string $goods_number
     * @param int $nums
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function itemForGoods (
        int $goods_id,
        string $goods_number,
        int $nums): array
    {
        $goods_number = Functions::str_sort($goods_number);
        $model      = new \app\model\GoodsAttributeAttach();
        $result     = $model
//            ->fetchSql(true)
            ->alias('gaa')
            ->join('goods g', 'gaa.goods_id=g.id')
            ->where(['gaa.goods_id' => $goods_id, 'gaa.number' => $goods_number, 'g.status' => 99])
            ->field('gaa.goods_id,g.price,g.status,gaa.number as goods_number,gaa.price as real_price,g.title,gaa.thumb,gaa.attach')
            ->find()
            ->toArray();
        $result['spec'] = '';
        foreach ($result['attach'] as $v) {
            $result['spec'] .= ($v->name).' ';
        }
        $result['number'] = $nums;
        unset($result['attach']);
        return Functions::result(
            STATUS_CODE::SUCCESS,
            [$result]
        );
    }
    /**
     * @purpose 通过购物车ID获取购物车商品信息
     * @param $ids
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function itemForCart (array $ids, int $uid) {
        $model      = new ShoppingCart();
        $result     = $model
            ->alias('sc')
            ->join('goods g', 'sc.goods_id=g.id')
            ->join('goods_attribute_attach gaa', 'sc.goods_number=gaa.number and sc.goods_id=gaa.goods_id')
            ->where(['sc.id' => $ids,'sc.uid' => $uid, 'g.status' => 99])
            ->field('sc.id,sc.goods_id,sc.goods_price as price,sc.goods_number,sc.number,sc.goods_title as title,sc.goods_spec as spec,sc.goods_thumb as thumb,g.status,gaa.price as real_price')
            ->order('sc.create_at desc')
            ->select();
        return Functions::result(
            STATUS_CODE::SUCCESS,
            $result
        );
    }

    /**
     * @purpose 取消未支付的订单
     * @param string $order_no
     * @param string $reason
     * @param int $uid
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function cancel (string $order_no, string $reason, int $uid): array
    {
        $model      = new \app\model\Order();
        $where      = ['order_no' => $order_no, 'uid' => $uid];
        $order_info     = $model
            ->where($where)
            ->field('id,status')
            ->find();
        if ($order_info->status !== 1) {
            return Functions::result(
                STATUS_CODE::ORDER_STATUS_ERROR,
                '错误的订单状态!'
            );
        }
        $process    = new OrderProcess();
        $process_data = [];
        $process_data['order_id']       = $order_info->id;
        $process_data['status']         = 4;
        $process_data['operator_type']  = 1;
        $process_data['operator_id']    = 1;
        $process_data['description']    = '订单被取消';
        $model->startTrans();
        $result     = $model
            ->isUpdate(true)
            ->save(['status' => 4, 'cancel_reason' => $reason],
                $where);
        $process_result  = $process
            ->data($process_data)
            ->save();

        if ($result && $process_result) {
            $model->commit();
            return Functions::result(
                STATUS_CODE::SUCCESS,
                '取消成功!'
            );
        }
        $model->rollback();
        return Functions::result(
            STATUS_CODE::UPDATE_FAIL,
            '取消失败!'
        );

    }

    /**
     * @purpose 删除订单
     * @param string $order_no
     * @param int $uid
     * @return array
     */
    public static function delete (string $order_no, int $uid): array
    {
        $model       = new \app\model\Order();
        $where      = ['order_no' => $order_no, 'uid' => $uid];
        $status     = $model->where($where)->value('status');
        if (!in_array($status, [4,6,7])) {
            return Functions::result(
                STATUS_CODE::ORDER_STATUS_ERROR,
                '错误的订单状态!'
            );
        }
        $result     = $model
            ->isUpdate(true)
            ->save(['status' => 5],
                $where);
        if ($result) {
            return Functions::result(
                STATUS_CODE::SUCCESS,
                '删除成功!'
            );
        }
        return Functions::result(
            STATUS_CODE::UPDATE_FAIL,
            '删除失败!'
        );
    }
}